﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.IO;
using System.Drawing.Imaging;
using Draco.OWF.Studio.Utility;
using Draco.OWF.Studio.Common.Geometry;

namespace Draco.OWF.Studio.Designer
{
    public delegate void ActivityFaceMoveEventHandler(ActivityFacet face, ActivityFaceMoveEventArgs e);
    public delegate void DrawRouteEventHandler(ActivityFacet face, DrawRouteEventArgs e);
    /// <summary>
    /// Interaction logic for ActivityFace.xaml
    /// </summary>
    public partial class ActivityFacet : Canvas
    {
        private Size m_ImageSize = new Size(48, 48);
        private IDesignerEnv m_Env;
        private MoveAction MoveAction { get { return m_Env.ActivityFacetDragAction; } }
        public IActivity Activity{get;private set;}
        
        public event ActivityFaceMoveEventHandler ActivityFacetMove;
        public event DrawRouteEventHandler DrawRouteStart;
        public event DrawRouteEventHandler DrawRouteMoving;
        public event DrawRouteEventHandler DrawRouteComplete;

        public double X { get { return Activity.Render.X; } private set { Activity.Render.X = value; } }
        public double Y { get { return Activity.Render.Y; } private set { Activity.Render.Y = value; } }
        
        public ActivityFacet(IActivity activity,UIElement parent, IDesignerEnv env)
        {
            if (activity == null || env == null)
                throw new ArgumentNullException();
            this.Activity = activity;
            this.m_Env = env;

            InitializeComponent();
            
            InitActivity(Activity);
            this.IconImg.ContextMenu = CreateContextMenu();

            ElementMoveWrapper Wrapper = new ElementMoveWrapper(this.IconImg, parent);
            Wrapper.ElementMoveStart += new ElementMoveEventHandler(Wrapper_ElementMoveStart);
            Wrapper.ElementMoving += new ElementMoveEventHandler(Wrapper_ElementMove);
            Wrapper.ElementMoveComplete += new ElementMoveEventHandler(Wrapper_ElementMoveComplete);

            Wrapper.ElementLeftClick += new MouseButtonEventHandler(Wrapper_ElementLeftClick);
            Wrapper.ElementRightClick += new MouseButtonEventHandler(Wrapper_ElementRightClick);
        }

        public Point CenterPoint 
        {
            get 
            {
                return new System.Windows.Point(X +m_ImageSize.Width / 2, Y + m_ImageSize.Height / 2);
            }
        }
        public Rect Rect 
        {
            get 
            {
                return new Rect(X, Y, m_ImageSize.Width, m_ImageSize.Height); 
            }
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="p"></param>
        /// <returns></returns>
        public bool HitTest(Point p)
        {
            GeoRect rect = new GeoRect(this.Rect);
            PointRectRelation relation = rect.GetPointRectRelationship(p);
            return relation == PointRectRelation.Inside || relation == PointRectRelation.On;
        }

        #region Click
        void Wrapper_ElementLeftClick(object sender, MouseButtonEventArgs e)
        {

        }
        void Wrapper_ElementRightClick(object sender, MouseButtonEventArgs e)
        {
            
        }
        #endregion

        #region Move
        void Wrapper_ElementMoveStart(object sender, ElementMoveEventArgs e)
        {
            if (this.MoveAction == Designer.MoveAction.DrawRouteFacet)
            {
                if(this.DrawRouteStart!=null)
                    this.DrawRouteStart(this,new DrawRouteEventArgs(e));
            }
        }
        /// <summary>
        /// Activity Face moving
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Wrapper_ElementMove(object sender, ElementMoveEventArgs e)
        {
            if (this.MoveAction == Designer.MoveAction.MoveActivityFacet)
            {
                this.X += e.DeltaX;
                this.Y += e.DeltaY;
                if (this.ActivityFacetMove != null)
                    this.ActivityFacetMove(this, new ActivityFaceMoveEventArgs(e));
            }
            else if (this.MoveAction == Designer.MoveAction.DrawRouteFacet)
            {
                if(this.DrawRouteMoving!=null)
                    this.DrawRouteMoving(this, new DrawRouteEventArgs(e));
            }
        }

        void Wrapper_ElementMoveComplete(object sender, ElementMoveEventArgs e)
        {
            if (this.MoveAction == Designer.MoveAction.DrawRouteFacet)
            {
                if (this.DrawRouteComplete != null)
                    this.DrawRouteComplete(this, new DrawRouteEventArgs(e));
            }
        }
        #endregion

        private void InitActivity(IActivity activity)
        {
            IActivityRender render = activity.Render;
            System.Drawing.Image icon = render.Icon;
            if (icon != null)
            {
                this.IconImg.Source = System.Drawing.ImageConvertion.ToBitmapSource(icon);
            }
            else
            {
                this.IconImg.Source = new BitmapImage(new Uri("pack://application:,,,/Images/Activity.png"));
            }
            this.TxtName.Text = activity.DisplayName;
        }
        private ContextMenu CreateContextMenu()
        {
            ContextMenu menu = new ContextMenu();
            MenuItem item = new MenuItem();
            item.SetResourceReference(MenuItem.HeaderProperty, "Delete");
            menu.Items.Add(item);
            menu.Items.Add("abc");
            return menu;
        }
    }
    public class ActivityFaceMoveEventArgs : ElementMoveEventArgs
    {
        public ActivityFaceMoveEventArgs(MouseEventArgs arg, Point startMousePoint, Point previousMousePoint, Point currentMousePoint)
            : base(arg, startMousePoint, previousMousePoint, currentMousePoint)
        {
        }
        public ActivityFaceMoveEventArgs(ElementMoveEventArgs arg)
            :base(arg.MouseEventArgs,arg.StartMousePoint,arg.PreviousMousePoint,arg.CurrentMousePoint)
        { 
        }
    }
    public class DrawRouteEventArgs : ElementMoveEventArgs
    {
        public DrawRouteEventArgs(MouseEventArgs arg, Point startMousePoint, Point previousMousePoint, Point currentMousePoint)
            : base(arg, startMousePoint, previousMousePoint, currentMousePoint)
        {
        }
        public DrawRouteEventArgs(ElementMoveEventArgs arg)
            : base(arg.MouseEventArgs, arg.StartMousePoint, arg.PreviousMousePoint, arg.CurrentMousePoint)
        {
        }
    }
}
